import java.io.Serializable;

/*this class is to represent a single musical note as according to it's frequency*/
public class Note implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	static double root12of2 = 1.0594630943592952645618252949463417;//Math.pow(2, 1/12);
	static double root24of2 = 1.029302236643492028782371800773921996370292842214179051;// Math.pow(2, 1/24);
	static int lowA = 55; //The lowest note A supported in the project
	static int highA = 28160; //The highest note A supported in the project
	
	private FreqNote musicNote; //The closest note to the frequency 
	private double originalFrequencey; //The frequency the user hum
	
	
	/*
	 * creates a new Note from a given frequency using a hashing algorithm
	 */
	public Note(double frequencey){
		FreqNote note = findClosestNote(frequencey);
		this.musicNote = note;
		this.setOriginalFrequencey(frequencey);
	}
		
	/*
	 * finds the closest frequency that is a musical note to the given frequency
	 */
	public static FreqNote findClosestNote(double frequencey){
		if (frequencey == 0 || frequencey > highA ||frequencey < lowA)
			return new FreqNote(0);
		else {
			FreqNote note1 = new FreqNote(lowA);
			FreqNote note2 = new FreqNote (lowA, 1);
			while(note2.getFreqOfNote() < frequencey) {
				note1.increaseByHalfTune();
				note2.increaseByHalfTune();
			}
			FreqNote note3 = new FreqNote (note1);
			note3.increaseByQuaterTune();
			if (note3.getFreqOfNote() < frequencey)
				return note2;
			else
				return note1;
		}
	}
	
	


	/*
	 * get the number in the Octave of the closest note.
	 */
	public int getMusicalNote(){
		return this.musicNote.getTune();
	}

	
	/*
	 * Get the octave of a frequency.
	 */
	public static double getOct(double note) {
		double A = lowA;
		while (A*2 < note)
			A*=2;
		return A;
	}

	public void setOriginalFrequencey(double originalFrequencey) {
		this.originalFrequencey = originalFrequencey;
	}

	public double getOriginalFrequencey() {
		return originalFrequencey;
	}
	
	public String toString(){
		return "" +this.getMusicalNote();
	}
	
}
